home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Systemmonitors
/
Snoopy
/
Sources
/
main.asm
next >
Wrap
Assembly Source File
|
1996-09-26
|
43KB
|
1,658 lines
incpath include:
maclib sm.mac
macfile macro.i
macfile snoopy.i
macfile macros/main
macfile extern/parse
macfile extern/misc
macfile macros/startup
macfile extern/patch
DETACHSTARTUPARGS <argTemplate>,<argFirst>,maincode,4096
maincode bsr Setup
tst d0
bne .FAIL
;-------------- if the user only wants to quit, don't show anything
tst.l (argQuit)
bne .QUITONLY
;-------------- give out initial welcome to the user
move.l (currentInstance),(outputArgs)
SHOWMSG hello
;-------------- main loop ! Wait for signals to arrive, and process them
.MainLoop move.l (waitsignals),d0
CALL Wait,<(execBase).w>
move.l d0,(signals)
;-------------- CTRL+C terminates the program
BRBS #SIGBREAKB_CTRL_C,d0,.DONE
;-------------- if we got a message, then answer it
move.l d0,d1
and.l (answersignal),d1
tst.l d1
beq.b .NoMessage
bsr HandleReply
bra.b .MainLoop
.NoMessage
;-------------- CTRL+D disables output
BRBC.B #SIGBREAKB_CTRL_D,d0,.DisableOutput
tst.b (outputactive)
beq.b .MainLoop
move.b #FALSE,(outputactive)
SHOWMSG disableout
bra .MainLoop
.DisableOutput
;-------------- CTRL+E disables output
BRBC.B #SIGBREAKB_CTRL_E,d0,.EnableOutput
tst.b (outputactive)
bne.b .MainLoop
move.b #TRUE,(outputactive)
SHOWMSG enableout
bra .MainLoop
.EnableOutput
;-------------- CTRL+F toggles the task info feature
BRBC.B #SIGBREAKB_CTRL_F,d0,.ToggleTI
tst.l (argTaskInfo)
bne.b .TI_Disabled
move.l #TRUE,(argTaskInfo)
SHOWMSG TIenabled
bra .MainLoop
.TI_Disabled SHOWMSG TIdisabled
clr.l (argTaskInfo)
.ToggleTI
bra .MainLoop
;-------------- sorry, calls still active
.CALLSACTIVE lea (activeCallsErr,pc),a0
move.l (ActiveCalls),(outputArgs)
jsr ShowErrorMessage
bra .MainLoop
.DONE tst.l (ActiveCalls)
bne.b .CALLSACTIVE
bsr RemoveFunctions ; remove all functions
tst.w d0
beq .MainLoop
.QUITONLY bsr Cleanup
moveq #RETURN_OK,d0
rts
.FAIL bsr RemoveFunctions ; MUST succeed, otherwise we're really in trouble
bsr Cleanup
moveq #RETURN_ERROR,d0
rts
***********************************************************************************
;--------------
ENTRY Setup,d1-d7/a0-a6
clr.l (ActiveCalls)
;-------------- empty all lists used
prepare hides
prepare shows
prepare bases
prepare watches
prepare deviceBases
prepare aliases
prepare defines
prepare resources
move.b #TRUE,(outputactive)
;-------------- open librarys needed
openlib int
openlib icon
bsr ReadWBArgs
;-------------- perhaps we only need to remove any running Snoopys ?!
tst.l (argQuit)
beq.b .DONTQUIT
bsr QuitSnoopyInstances
moveq #TRUE,d0
bra Setup_done
.DONTQUIT
;-------------- build taskname to be removeable
bsr BuildSnoopysTaskname
;-------------- try to open script file
move.l (argScript),d0
bne.b .CallParser
move.l #defaultScript,d0
.CallParser movea.l d0,a0
jsr ParseScriptFile
tst d0
bne .NODOSBASE ; this looks strange but it works just fine
;-------------- defines and aliases are not needed any longer, so they can be
;-------------- freed immediately
remlist defines,sdef_SIZEOF
remlist aliases,salias_SIZEOF
;-------------- try to find SegTracker(tm)
clr.l (SegTracker)
lea (SegTrackerName,pc),a1
CALL FindSemaphore,<(execBase).w>
tst.l d0
beq.b .NOSEMAPHORE
movea.l d0,a0
move.b #TRUE,(SegTrackerOn)
move.l (segs_Find,a0),(SegTracker)
.NOSEMAPHORE
;-------------- create msgport
CALL CreateMsgPort,<(execBase).w>
move.l d0,(myport)
beq .NOMSGPORT
move.l (ThisTask,a6),(thistask)
movea.l d0,a1
move.l #currentPortName,(LN_NAME,a1)
moveq #0,d0
move.b (MP_SIGBIT,a1),d0
moveq #1,d1
lsl.l d0,d1
move.l d1,(answersignal)
or.l #MASK_SIGNALS,d1
move.l d1,(waitsignals)
CALL AddPort
;-------------- open CON: window
move.l #windowName,d1
tst.b (outputMemory)
beq.b .NOOUTPUTKEYWRD
move.l #outputMemory,d1
.NOOUTPUTKEYWRD tst.l (argOutput)
beq.b .DefaultWindow
move.l (argOutput),d1
.DefaultWindow move.l #MODE_READWRITE,d2
CALL Open,<(dosBase)>
move.l d0,(window)
beq.b .NOWINDOW
jsr SetCmdlineSHOWs
;-------------- patch functions
bsr PatchFunctions
tst.w d0
beq.b .NODOSBASE
;-------------- set my priority (if applicable)
move.l (priority),d0
tst.l (argPri)
beq.b .NOPRICMD
movea.l (argPri),a0
move.l (a0),d0
.NOPRICMD movea.l (execBase).w,a6
movea.l (ThisTask,a6),a1
CALL SetTaskPri
moveq #RETURN_OK,d0
bra.b Setup_done
.NOWINDOW lea (nowindowErr,pc),a0
bra.b .FAIL
.NOMSGPORT lea (nomsgportErr,pc),a0
.FAIL jsr ShowErrorMessage
.NODOSBASE moveq #RETURN_ERROR,d0
DONE Setup
***********************************************************************************
;--------------
ENTRY Cleanup,d0-d7/a0-a6
bsr RemoveDeviceBases
bsr RemoveLibraryBases
;-------------- close window
move.l (window),d1
beq.b .NoWindow
CALL Close,<(dosBase)>
.NoWindow
;-------------- remove msgport
move.l (myport),d0
beq.b .NoMsgPort
movea.l d0,a1
CALL RemPort,<(execBase).w>
bsr RemoveAllMessages
movea.l (myport),a0
CALL DeleteMsgPort
.NoMsgPort
;-------------- close CLI arguments
move.l (argRdargs),d1
beq.b .NoRdArgs
CALL FreeArgs,<(dosBase)>
.NoRdArgs
;-------------- close librarys
closelb int
closelb icon
;-------------- remove structures
remlist defines,sdef_SIZEOF
remlist aliases,salias_SIZEOF
remlist bases,sbase_SIZEOF
remlist resources,sbase_SIZEOF
remlist hides,stask_SIZEOF
remlist shows,stask_SIZEOF
remlist watches,spatch_SIZEOF
remlist deviceBases,sdevbase_SIZEOF
DONE Cleanup
***********************************************************************************
;-------------- remove all remaining messages from the port (so that we can be sure
;-------------- we have not lost any memory
;--------------
ENTRY RemoveAllMessages,d0-d7/a0-a6
;-------------- free message memory
movea.l (execBase).w,a6
.LOOP movea.l (myport),a0
CALL GetMsg
tst.l d0
beq.b .DONE
movea.l d0,a1
move.l #smsg_SIZEOF,d0
CALL FreeMem
bra.b .LOOP
.DONE DONE RemoveAllMessages
***********************************************************************************
;-------------- remove all library bases
ENTRY RemoveLibraryBases,d0-d7/a0-a6
lea (bases),a5
movea.l (LH_HEAD,a5),a5
movea.l (execBase).w,a6
.BASELOOP tst.l (LN_SUCC,a5) ; a5 = current node
beq.b .BASEDONE
move.l (sbase_Library,a5),d0
beq.b .NEXTBASE
clr.l (sbase_Library,a5)
movea.l d0,a1
CALL CloseLibrary
.NEXTBASE movea.l (LN_SUCC,a5),a5
bra.b .BASELOOP
.BASEDONE DONE RemoveLibraryBases
***********************************************************************************
;-------------- remove all device bases
ENTRY RemoveDeviceBases,d0-d7/a0-a6
lea (deviceBases),a5
movea.l (LH_HEAD,a5),a5
.BASELOOP2 tst.l (LN_SUCC,a5) ; a5 = current node
beq.b .BASEDONE2
;-------------- remove message port
;move.l (sdevbase_MsgPort,a5),d0
;beq.b .NOMSGPORT
;movea.l d0,a0
;CALL DeleteMsgPort,<(execBase).w>
.NOMSGPORT
;-------------- remove device bases
move.l (sdevbase_Device,a5),d0
beq.b .NEXTBASE2
clr.l (sdevbase_Device,a5)
movea.l d0,a1
CALL Forbid,<(execBase).w>
subq.w #1,(LIB_OPENCNT,a1)
move.b (LIB_FLAGS,a1),d0
bset #LIBB_CHANGED,d0
move.b d0,(LIB_FLAGS,a1)
CALL SumLibrary
CALL Permit
;-------------- free all patches for this device)
.NEXTBASE2 lea (sdevbase_Patches,a5),a0
move.l #spatch_SIZEOF,d0
jsr RemoveList
movea.l (LN_SUCC,a5),a5
bra.b .BASELOOP2
.BASEDONE2 DONE RemoveDeviceBases
***********************************************************************************
;-------------- build a unique taskname for the current copy of Snoopy [this is
;-------------- required even if option QUIT was given]
;--------------
ENTRY BuildSnoopysTaskname,d0-d7/a0-a6
moveq #0,d7 ; used to count the number of Snoopys installed
;-------------- examine waiting tasks
CALL Forbid,<(execBase).w> ; stop multitasking
lea (TaskWait,a6),a4
movea.l (LH_HEAD,a4),a4
.LOOP1 tst.l (LN_SUCC,a4)
beq.b .DONE1
bsr.b .FINDSNOOPY
movea.l (LN_SUCC,a4),a4
bra.b .LOOP1
;-------------- examine ready tasks
.DONE1 lea (TaskReady,a6),a4
movea.l (LH_HEAD,a4),a4
.LOOP2 tst.l (LN_SUCC,a4)
beq.b .DONE2
bsr.b .FINDSNOOPY
movea.l (LN_SUCC,a4),a4
bra.b .LOOP2
.DONE2 CALL Permit,<(execBase).w> ; reallow multitasking
addq.w #1,d7 ; "addq.l" would be too pretentious, really.... ;-)
move.l d7,(currentInstance)
;-------------- build new taskname and portname
lea (outputArgs),a1
move.l d7,(a1)
lea (taskNameFormat,pc),a0
lea (currentTaskName),a2
jsr SPrintf
lea (taskPortFormat,pc),a0
lea (currentPortName),a2
jsr SPrintf
;-------------- install taskname
movea.l (ThisTask,a6),a0
move.l #currentTaskName,(LN_NAME,a0)
bra.b BuildSnoopysTaskname_done
;-------------- trys to find out the name for a task
.FINDSNOOPY move.l (LN_NAME,a4),d0
beq.b .SKIP
movea.l d0,a0
lea (taskNameFormat,pc),a1
moveq #taskNameFormat_SIZEOF-1,d0
.STRCMP move.b (a0)+,d1
cmp.b (a1)+,d1
bne.b .SKIP
dbra d0,.STRCMP
moveq #STVFORMAT_DEC,d0
jsr StringToValue
cmp.w d7,d0
bls.b .SKIP
move.w d0,d7
.SKIP rts
DONE BuildSnoopysTaskname
***********************************************************************************
;-------------- yeah, we got ourselfs a message; now show it and go home
;--------------
ENTRY HandleReply,d0-d7/a0-a6
.LOOP movea.l (myport),a0
CALL GetMsg,<(execBase).w>
move.l d0,(message)
tst.l d0
beq HandleReply_done
movea.l d0,a5 ; a5=message
;-------------- output handling is different if its a device message
move.w (smsg_Type,a5),d0
BRBS #MSGTYPEB_DEBUG,d0,.HANDLEDEBUG
BRBS #MSGTYPEB_DEVICE,d0,.HANDLEDEVICE
;-------------- now we have the message and its data, so lets go for it !
tst.b (outputactive)
beq .SkipOutput
;-------------- if the task is hidden, skip output
movea.l (smsg_Task,a5),a0
bsr IsTaskHidden
tst d0
bne.b .SkipOutput
;-------------- handle
movea.l (smsg_Info,a5),a0
move.l (spatch_Flags,a0),d0
BRBC.B #SINFOB_SKIPSIMILAR,d0,.SKIPSIMILAR
move.l a0,d0
cmp.l (lastMessage),d0
beq.b .SkipOutput
move.l d0,(lastMessage)
.SKIPSIMILAR
;-------------- show extended task info if applicable
tst.l (argTaskInfo)
beq.b .NoTaskInfo
movea.l (smsg_Task,a5),a0
bsr ShowTaskInfo
.NoTaskInfo
;-------------- if SEGTRACKER is there, show segment of pc
tst.l (SegTracker)
beq.b .NoSegTracker
movea.l (smsg_RegsBeforeCall+sregs_I7,a5),a0 ; a0=address to show
movea.l (smsg_Info,a5),a1 ; a1=PatchInfo
move.l (spatch_Flags,a1),d0
BRBS.B #SINFOB_NOSEGTRACKER,d0,.NoSegTracker
bsr ShowSegTracker
.NoSegTracker
;-------------- prepare output data
.SHOWMESSAGE movea.l (smsg_Info,a5),a4 ; a4=PatchInfo
lea (spatch_Arguments,a4),a1 ; a1 = current position in argument template
moveq #TRUE,d0
bsr SetupOutputData
;-------------- send message
lea.l (spatch_Template,a4),a0
jsr ShowMessage
move.l (window),d1
CALL Flush,<(dosBase)>
bsr.b .NEWLINE
;-------------- free message memory
.SkipOutput movea.l (message),a1
move.l #smsg_SIZEOF,d0
CALL FreeMem,<(execBase).w>
bra .LOOP
.NEWLINE move.l (window),d1
move.l #newlineMsg,d2
moveq #1,d3
CALL Write,<(dosBase)>
move.l (window),d1
CALL Flush
rts
;---------------------------------------------------------------------------
;-------------- this is were we deal with USER-DEBUG messages
;--------------
;-------------- skip if output deactivated
.HANDLEDEBUG tst.b (outputactive)
beq .LISTDONE
;-------------- if the task is hidden, skip output
movea.l (message),a5
movea.l (sumsg_Task,a5),a0
bsr IsTaskHidden
tst d0
bne .LISTDONE
;-------------- show extended task info if applicable
tst.l (argTaskInfo)
beq.b .NoDebugTaskInfo
movea.l (sumsg_Task,a5),a0
bsr ShowTaskInfo
.NoDebugTaskInfo
;-------------- if SEGTRACKER is there, show segment of pc
tst.l (SegTracker)
beq.b .NoDebugSegTracker
movea.l (sumsg_RegsBeforeCall+sregs_I7,a5),a0 ; a0=address to show
;-------------- SKIPSEGTRACKER not supported for Debug calls
bsr ShowSegTracker
.NoDebugSegTracker
move.l (sumsg_Template,a5),d0
beq .DebugUseDefaultTemplate
movea.l d0,a4
lea (4,a4),a1 ; a1 = current position in argument template
bsr SetupOutputData
moveq #FALSE,d0
bsr SetupOutputData
;-------------- send message
movea.l (sumsg_Template,a5),a0
movea.l (a0),a0
jsr ShowMessage
move.l (window),d1
CALL Flush,<(dosBase)>
bsr .NEWLINE
bra .LISTDONE
;-------------- no explicit user template, use default
.DebugUseDefaultTemplate
lea (outputArgs),a0
lea (sumsg_RegsBeforeCall,a5),a1
SAVEDEBUGREGISTERS
lea (sumsg_RegsAfterCall,a5),a1
SAVEDEBUGREGISTERS
lea (DebugDefTempMsg,pc),a0
jsr ShowMessage
move.l (window),d1
CALL Flush,<(dosBase)>
bra .LISTDONE
;---------------------------------------------------------------------------
;-------------- the rest of this function deals with the device messages
;--------------
;-------------- skip if output deactivated
.HANDLEDEVICE tst.b (outputactive)
beq .LISTDONE
;-------------- if the task is hidden, skip output
movea.l (message),a4
movea.l (sdmsg_Task,a4),a0
bsr IsTaskHidden
tst d0
bne .LISTDONE
;-------------- lets see if we understand this message
movea.l (sdmsg_DeviceBase,a4),a5
lea (sdevbase_Patches,a5),a5
movea.l (LH_HEAD,a5),a5 ; a5=current patch
move.w (sdmsg_SIZEOF+IO_COMMAND,a4),d0 ; d0=current command
.LISTLOOP tst.l (LN_SUCC,a5)
beq.b .LISTDONE
;-------------- offset=-1 -> show always
cmpi.w #-1,(spatch_Offset,a5)
beq.b .SHOWALWAYS
cmp.w (spatch_Offset,a5),d0
bne.b .SKIPLIST
;-------------- show only if the appropriate bits are set
.SHOWALWAYS move.l (spatch_Flags,a5),d0
move.w (smsg_Type,a4),d1
BRBS.B #MSGTYPEB_BEGINIO,d1,.ITSBEGINIO
BRBC.B #SINFOB_ABORTIO,d0,.SKIPLIST
bra.b .ITSOK
.ITSBEGINIO BRBC.B #SINFOB_BEGINIO,d0,.SKIPLIST
.ITSOK
;-------------- show extended task info if applicable
tst.l (argTaskInfo)
beq.b .NoDTaskInfo
movea.l (sdmsg_Task,a4),a0
bsr ShowTaskInfo
;-------------- if SEGTRACKER is there, show segment of pc
.NoDTaskInfo tst.l (SegTracker)
beq.b .NoDSegTracker
movea.l (sdmsg_PC,a4),a0 ; a0=address to show
move.l (spatch_Flags,a5),d0
BRBS.B #SINFOB_NOSEGTRACKER,d0,.NoDSegTracker
bsr ShowSegTracker
.NoDSegTracker movea.l a5,a0
bsr.b ShowDeviceMessage
bsr .NEWLINE
bra.b .LISTDONE
.SKIPLIST movea.l (LN_SUCC,a5),a5
bra.b .LISTLOOP
;-------------- free message memory and return to main loop
.LISTDONE movea.l (message),a1
moveq #0,d0
move.w (MN_LENGTH,a1),d0
CALL FreeMem,<(execBase).w>
bra .LOOP
DONE HandleReply
***********************************************************************************
;--------------
;-------------- => a0: (struct SnoopyPatch *)
;--------------
ENTRY ShowDeviceMessage,d0-d7/a0-a6
;-------------- prepare output data
movea.l (message),a5
movea.l a0,a4 ; a4 = patch
bsr SetupDeviceOutputData
;-------------- send message
lea.l (spatch_Template,a4),a0
jsr ShowMessage
move.l (window),d1
CALL Flush,<(dosBase)>
DONE ShowDeviceMessage
***********************************************************************************
;--------------
;-------------- -> a4: Patch Info
;-------------- a5: Register Data
ENTRY SetupDeviceOutputData,d0-d7/a0-a6
lea (outputArgs),a0 ; a0 = current output offset
lea (spatch_Arguments,a4),a1 ; a1 = current position in argument template
movea.l (message),a3
lea (sdmsg_SIZEOF,a3),a2
;-------------- done ? then lets go !
.LOOP move.w (sarg_Opcode,a1),d0
cmpi.w #REG_DONE,d0
beq.b SetupDeviceOutputData_done
;-------------- if REGB_INDIRECT is given, I display internal data!!!!!!!!!
BRBS #REGB_INDIRECT,d0,.SHOWINTERNAL
BRBS.B #REGB_BYTE,d0,.SETBYTE
BRBS.B #REGB_WORD,d0,.SETWORD
.SETLONG move.l (sarg_Offset,a1),d0
move.l (a2,d0.l),(a0)+
bra.b .NEXT
.SETWORD move.l (sarg_Offset,a1),d0
move.w (a2,d0.l),(a0)+
bra.b .NEXT
.SETBYTE move.l (sarg_Offset,a1),d0
move.b (a2,d0.l),d0
ext.w d0
move.w d0,(a0)+
.NEXT lea (sarg_SIZEOF,a1),a1
bra.b .LOOP
;--------------
.SHOWINTERNAL andi.w #%111,d0 ; get bit number
tst.b d0
beq.b .SHOWCALLTYPE
;-------------- NOT SUPPORTED!
bra.b .NEXT
.SHOWCALLTYPE move.l #abortIOMsg,d0
move.w (smsg_Type,a3),d1
BRBC.B #MSGTYPEB_BEGINIO,d1,.ISABORTIO
move.l #beginIOMsg,d0
.ISABORTIO move.l d0,(a0)+
bra.b .NEXT
DONE SetupDeviceOutputData
***********************************************************************************
;-------------- checks if the current task is hidden, returns TRUE if so
ENTRY IsTaskHidden,d1-d7/a0-a6
;-------------- a3 = task pointer
movea.l a0,a3
;-------------- find taskname to a4
movea.l a0,a1
cmpi.b #NT_PROCESS,(LN_TYPE,a0)
bne.b .DEFAULT
tst.l (pr_TaskNum,a0)
beq.b .DEFAULT
move.l (pr_CLI,a0),d0
lsl.l #2,d0
movea.l d0,a0
move.l (cli_CommandName,a0),d0
lsl.l #2,d0
addq.l #1,d0
movea.l d0,a4
bra.b .DONE
.DEFAULT movea.l (LN_NAME,a0),a4
.DONE
;-------------- handle SHOWs
tst.b (showsactive)
beq.b .NoSHOWs
lea (shows),a5
bsr.b CheckIfIsInList
not.l d0
bra.b IsTaskHidden_done
.NoSHOWs
;-------------- handle HIDEs
lea (hides),a5
bsr.b CheckIfIsInList
DONE IsTaskHidden
***********************************************************************************
;-------------- checks if an entry can be found in a list
;--------------
;-------------- -> a5: struct List *HEAD
;-------------- a4: STRPTR name
;-------------- a3: APTR task
;-------------- <- d0: TRUE=Member of this list, FALSE otherwise
;--------------
ENTRY CheckIfIsInList,d1-d7/a0-a6
cmpa.l #0,a4
beq.b .NotInList
movea.l (LH_HEAD,a5),a5
.LOOP tst.l (LN_SUCC,a5) ; a5 = current node
beq.b .NotInList
movea.l a4,a0
move.l (stask_Pointer,a5),d0
beq.b .CHECKNAME
cmpa.l d0,a3
beq.b .InList
.CHECKNAME lea (stask_Name,a5),a1
;-------------- NEW: exact matching enabled
tst.l (argMatch)
bne.b .STRCMP
.STRICMP move.b (a1)+,d0
beq.b .InList
move.b (a0)+,d1
UCASE d0
UCASE d1
cmp.b d1,d0
beq.b .STRICMP
movea.l (LN_SUCC,a5),a5
bra.b .LOOP
.NotInList moveq #0,d0
bra.b CheckIfIsInList_done
;-------------- NEW: enable exact matching
.STRCMP move.b (a1)+,d0
beq.b .SEEMSTOMATCH
move.b (a0)+,d1
cmp.b d1,d0
beq.b .STRCMP
movea.l (LN_SUCC,a5),a5
bra.b .LOOP
.SEEMSTOMATCH tst.b (a0)+
bne.b .LOOP
.InList moveq #-1,d0
DONE CheckIfIsInList
***********************************************************************************
;-------------- show an information line about the task that called this function
;--------------
ENTRY ShowTaskInfo,d1-d7/a0-a6
lea (taskinfoMsg),a1
move.l a0,(outputArgs)
cmpi.b #NT_PROCESS,(LN_TYPE,a0)
bne.b .DEFAULT
tst.l (pr_TaskNum,a0)
beq.b .DEFAULT
move.l (pr_CLI,a0),d0
lsl.l #2,d0
movea.l d0,a0
move.l (cli_CommandName,a0),(outputArgs+4)
lea (taskbcplMsg),a1
bra.b .DONE
.DEFAULT move.l (LN_NAME,a0),(outputArgs+4)
.DONE move.l a1,a0
;-------------- new: if SegTracker is enabled also, combine both outputs
tst.l (SegTracker)
beq.b .SHOWMESSAGE
move.l (outputArgs),(st_SegTaskAddr)
move.l (outputArgs+4),(st_SegFilename)
bra.b ShowTaskInfo_done
.SHOWMESSAGE jsr ShowMessage
move.l (window),d1
CALL Flush,<(dosBase)>
DONE ShowTaskInfo
***********************************************************************************
;--------------
;-------------- => a0: APTR address to show
ENTRY ShowSegTracker,d0-d7/a0-a6
move.l a0,d7 ; address to show
;-------------- the manual says we have to do this, so we do it
;-------------- (although we really couldn't care less, I tell you)
CALL Forbid,<(execBase).w>
;-------------- call SegTracker to find Hunk & Offset
movea.l d7,a0
lea (st_SegHunk),a1
lea (st_SegOffset),a2
movea.l (SegTracker),a6
jsr a6
tst.l d0
beq .NOTFOUND
;-------------- name found, copy it to our internal buffer
movea.l d0,a0
lea (errorMsgBuffer),a1
move.l a1,(st_SegName)
moveq #128-1,d0
.STRCPY move.b (a0)+,(a1)+
beq.b .STRCPYEND
dbra d0,.STRCPY
.STRCPYEND move.l d7,(st_SegAddress)
;-------------- lets see if we can find the address
movea.l d7,a0
lea (st_SegList),a1
movea.l a1,a2
movea.l (SegTracker),a6
jsr a6
move.l (st_SegList),d0
move.l (st_SegHunk),d1
cmp.l d0,d1
bne.b .USESEGLIST
move.l (st_SegOffset),d1
cmp.l d0,d1
bne.b .USESEGLIST
clr.l (st_SegList)
.USESEGLIST
;-------------- display the message
move.l (window),d1
move.l #SegTrackerMsg,d2
tst.l (argTaskInfo)
beq.b .NOTASKINFO
move.l #SegTrackerMsgTI,d2
.NOTASKINFO move.l #st_SegAddress,d3
CALL VFPrintf,<(dosBase)>
move.l (window),d1
CALL Flush
bra.b .DONE
;-------------- show warning
.NOTFOUND tst.l (flagSkipSegNotFound)
bne.b .DONE
lea (SegTrackerFail,pc),a0
jsr ShowMessage
move.l (window),d1
CALL Flush,<(dosBase)>
.DONE CALL Permit,<(execBase).w>
DONE ShowSegTracker
***********************************************************************************
;-------------- setup outputArgs to contain the registers as specified by
;-------------- the register template
;--------------
;-------------- -> a4: Patch Info
;-------------- a5: Register Data
;-------------- d0: BOOL type
ENTRY SetupOutputData,d0-d7/a0-a6
lea (outputArgs),a0 ; a0 = current output offset
move.w d0,d7
;-------------- done ? then lets go !
.LOOP move.w (sarg_Opcode,a1),d0
cmpi.w #REG_DONE,d0
beq SetupOutputData_done
;-------------- set correct register data to a2
tst.w d7
beq.b .DebugRegList
lea (smsg_RegsBeforeCall,a5),a2 ; a2 = regs before call ( default )
BRBC.B #REGB_RESULT,d0,.BeforeCall
lea (smsg_RegsAfterCall,a5),a2 ; a2 = regs before call ( default )
bclr #REGB_RESULT,d0
.BeforeCall bra.b .DebugRegListDone
.DebugRegList lea (sumsg_RegsBeforeCall,a5),a2 ; a2 = regs before call ( default )
BRBC.B #REGB_RESULT,d0,.DebugRegListDone
lea (sumsg_RegsAfterCall,a5),a2 ; a2 = regs before call ( default )
bclr #REGB_RESULT,d0
.DebugRegListDone
;-------------- use boolean tables if applicable
BRBS.B #REGB_BOOLEAN,d0,.UseBOOLEAN
;-------------- set correct jump table to a3
bclr #REGB_WORD,d0
lea (.JumpWORD,pc),a3
BRBC.B #REGB_LONG,d0,.NotLONG
lea (.JumpLONG,pc),a3
bclr #REGB_LONG,d0
.NotLONG BRBC.B #REGB_BYTE,d0,.NotBYTE
lea (.JumpBYTE,pc),a3
bclr #REGB_BYTE,d0
.NotBYTE
;-------------- find correct table offset
.ShowOutput BRBS.B #REGB_DATA,d0,.ISDATA
BRBC.B #REGB_ADDR,d0,.ISADDR
lea (8*4,a3),a3
bra.b .ISDATA
.ISADDR BRBC.B #REGB_INDIRECT,d0,.ISDATA
lea (2*8*4,a3),a3
.ISDATA
;-------------- now get the register data and save it
andi.w #%111,d0
lsl.w #2,d0
movea.l (a3,d0.w),a3
jsr a3
tst.w d7
bne.b .ITSAPATCH
.ITSADEBUGMSG lea (2,a1),a1
bra .LOOP
.ITSAPATCH lea (sarg_SIZEOF,a1),a1
bra .LOOP
;-------------- this isn't really 'clean code', but well it works
.UseBOOLEAN bclr #REGB_WORD,d0
lea (.JumpWORDBOOL,pc),a3
BRBC.B #REGB_LONG,d0,.NotLONGBOOL
lea (.JumpLONGBOOL,pc),a3
bclr #REGB_LONG,d0
.NotLONGBOOL BRBC.B #REGB_BYTE,d0,.NotBYTEBOOL
lea (.JumpBYTEBOOL,pc),a3
bclr #REGB_BYTE,d0
.NotBYTEBOOL bclr #REGB_BOOLEAN,d0
bra.b .ShowOutput
REGLIST LONG,L
REGLIST WORD,W
REGLIST BYTE,B
REGLIST LONGBOOL,LB
REGLIST WORDBOOL,WB
REGLIST BYTEBOOL,BB
SAVEREG A0
SAVEREG A1
SAVEREG A2
SAVEREG A3
SAVEREG A4
SAVEREG A5
SAVEREG D0
SAVEREG D1
SAVEREG D2
SAVEREG D3
SAVEREG D4
SAVEREG D5
SAVEREG D6
SAVEREG D7
SAVEREG I0
SAVEREG I1
SAVEREG I2
SAVEREG I3
SAVEREG I4
SAVEREG I5
SAVEREG I6
SAVEREG I7
.LONGBOOLEAN move.l #SuccessMsg,d1
tst.l d0
bne.b .LONGISTRUE
move.l #FailureMsg,d1
.LONGISTRUE move.l d1,(a0)+
rts
.WORDBOOLEAN move.l #SuccessMsg,d1
tst.w d0
bne.b .WORDISTRUE
move.l #FailureMsg,d1
.WORDISTRUE move.l d1,(a0)+
rts
DONE SetupOutputData
***********************************************************************************
;-------------- patch all functions in the watch list
;--------------
ENTRY PatchFunctions,d1-d7/a0-a6
;-------------- 1.PASS: patch all library functions
lea (watches),a5
movea.l (LH_HEAD,a5),a5
movea.l (execBase).w,a6
.LOOPPASS1 tst.l (LN_SUCC,a5) ; a5 = current node
beq.b .DONEPASS1
movea.l a5,a0
bsr.b InstallPatch
tst d0
beq.b .LIBFAILED
movea.l (LN_SUCC,a5),a5
bra.b .LOOPPASS1
;-------------- 2.PASS: patch all device functions
.DONEPASS1 lea (deviceBases),a5
movea.l (LH_HEAD,a5),a5
movea.l (execBase).w,a6
.LOOPPASS2 tst.l (LN_SUCC,a5) ; a5 = current node
beq.b .DONEPASS2
;-------------- patch BeginIO()
movea.l a5,a0
lea (BeginIO_Patch),a1
lea (BeginIO_Jump),a2
move.l (BeginIO_SIZEOF),d0
move.w #DEV_BEGINIO,d1
bsr InstallDevicesPatch
tst d0
beq.b .DEVFAILED
;-------------- patch AbortIO()
movea.l a5,a0
lea (AbortIO_Patch),a1
lea (AbortIO_Jump),a2
move.l (AbortIO_SIZEOF),d0
move.w #DEV_ABORTIO,d1
bsr InstallDevicesPatch
tst d0
beq.b .DEVFAILED
movea.l (LN_SUCC,a5),a5
bra.b .LOOPPASS2
.DONEPASS2 moveq #TRUE,d0
bra.b PatchFunctions_done
.DEVFAILED clr.l (sdevbase_IOSize,a5)
moveq #FALSE,d0
bra.b PatchFunctions_done
.LIBFAILED clr.l (spatch_Library,a5) ; to indicate failed patch
moveq #FALSE,d0
DONE PatchFunctions
***********************************************************************************
;-------------- Patch a system function
;--------------
;-------------- => a0: APTR Patchinfo
;-------------- <= d0: LONG success
;--------------
ENTRY InstallPatch,d1-d7/a0-a6
movea.l a0,a5
move.l a0,(PatchInfoStruct)
;-------------- allocate patch duplicate
move.l (Patch_SIZEOF),d0
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
CALL AllocMem,<(execBase).w>
tst.l d0
beq.b .FAIL
movea.l d0,a4
;-------------- setup original vector
movea.l (spatch_Library,a5),a1
move.w (spatch_Offset,a5),d1
addq.w #2,d1
move.l (a1,d1.w),(OriginalVector0+2)
move.l (a1,d1.w),(OriginalVector1+2)
move.l (a1,d1.w),(Patch_START+sphead_OriginalFunction)
;-------------- this is VERY important because otherwise Snoopy couldn't
;-------------- handle multiple instances so well
move.l (ThisTask,a6),(Patch_START+sphead_Owner)
;-------------- copy patch memory
movea.l a4,a0
lea (Patch_START),a1
move.l (Patch_SIZEOF),d0
subq.w #1,d0
.LOOP move.b (a1)+,(a0)+
dbra d0,.LOOP
;-------------- install new function
movea.l (spatch_Library,a5),a1
move.w (spatch_Offset,a5),d0
ext.l d0
movea.l d0,a0
move.l a4,d0
addi.l #sphead_SIZEOF,d0
CALL SetFunction
.SUCCESS moveq #TRUE,d0
bra.b InstallPatch_done
.FAIL moveq #FALSE,d0
DONE InstallPatch
***********************************************************************************
;-------------- Patch a system function
;--------------
;-------------- => a0: APTR Patchinfo
;-------------- <= d0: LONG success
;--------------
STRUCTURE idpStack,0
APTR idps_DeviceBase
APTR idps_BeginOfPatch
APTR idps_JumpAddress
APTR idps_SizeOfPatch
WORD idps_Offset
LABEL idps_SIZEOF
ENTRY InstallDevicesPatch,d1-d7/a0-a6,idps_SIZEOF,a5
move.l a0,(idps_DeviceBase,a5)
move.l a1,(idps_BeginOfPatch,a5)
move.l a2,(idps_JumpAddress,a5)
move.l d0,(idps_SizeOfPatch,a5)
move.w d1,(idps_Offset,a5)
;-------------- allocate patch duplicate
move.l (idps_SizeOfPatch,a5),d0
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
CALL AllocMem,<(execBase).w>
tst.l d0
beq.b .FAIL
movea.l d0,a4 ; a4 = patch memory
;-------------- setup original vector
movea.l (idps_DeviceBase,a5),a3 ; a3 = (SnoopyDeviceBase *)
movea.l (sdevbase_Device,a3),a1 ; a1 = (struct Device *)
move.w (idps_Offset,a5),d1 ; d1 = (function offset)
addq.w #2,d1
movea.l (idps_JumpAddress,a5),a0
move.l (a1,d1.w),(2,a0) ; set jump address
movea.l (idps_BeginOfPatch,a5),a0
move.l (a1,d1.w),(sphead_OriginalFunction,a0)
move.l (sdevbase_IOSize,a3),(sphead_Info,a0)
move.l a3,(sphead_DevicePtr,a0)
;-------------- copy patch memory
movea.l a4,a0
movea.l (idps_BeginOfPatch,a5),a1
move.l (ThisTask,a6),(sphead_Owner,a1)
move.l (idps_SizeOfPatch,a5),d0
subq.w #1,d0
.LOOP move.b (a1)+,(a0)+
dbra d0,.LOOP
;-------------- install new function
movea.l (sdevbase_Device,a3),a1
move.w (idps_Offset,a5),d0
ext.l d0
movea.l d0,a0
move.l a4,d0
addi.l #sphead_ExtSIZEOF,d0
CALL SetFunction
.SUCCESS moveq #TRUE,d0
bra.b InstallDevicesPatch_done
.FAIL moveq #FALSE,d0
DONE InstallDevicesPatch
***********************************************************************************
;-------------- remove the patch of all functions in the watch list
;--------------
ENTRY RemoveFunctions,d1-d7/a0-a6
lea (watches),a5
movea.l (LH_HEAD,a5),a5
movea.l (execBase).w,a6
.LOOP1 tst.l (LN_SUCC,a5) ; a5 = current node
beq.b .DONE1
movea.l a5,a0
bsr RemovePatch
tst.w d0
beq.b .FAILURE
movea.l (LN_SUCC,a5),a5
bra.b .LOOP1
.DONE1
lea (deviceBases),a5
movea.l (LH_HEAD,a5),a5
.LOOP2 tst.l (LN_SUCC,a5) ; a5 = current node
beq.b .DONE2
movea.l a5,a0
;-------------- unpatch BeginIO()
movea.l a5,a0
lea (BeginIO_Patch),a1
lea (BeginIO_Jump),a2
move.l (BeginIO_SIZEOF),d0
move.w #DEV_BEGINIO,d1
bsr RemoveDevicePatch
tst d0
beq.b .BEGINIOERR
;-------------- unpatch AbortIO()
movea.l a5,a0
lea (AbortIO_Patch),a1
lea (AbortIO_Jump),a2
move.l (AbortIO_SIZEOF),d0
move.w #DEV_ABORTIO,d1
bsr RemoveDevicePatch
tst d0
beq.b .ABORTIOERR
movea.l (LN_SUCC,a5),a5
bra.b .LOOP2
.DONE2 moveq #TRUE,d0
bra.b RemoveFunctions_done
;-------------- error in DEV_BEGINIO()
.BEGINIOERR move.l #closeBeginIoErr,d2
bra.b .DEVICEERROR
;-------------- error in DEV_ABORTIO()
.ABORTIOERR move.l #closeAbortIoErr,d2
.DEVICEERROR movea.l (sdevbase_Device,a5),a1
movea.l (LN_NAME,a1),a1
bra.b .SHOWERRORMSG
;-------------- show error messages
.FAILURE lea (spatch_Template,a5),a1
move.l #closesnoopyErr,d2
.SHOWERRORMSG move.l a1,(outputArgs)
move.l (window),d1
move.l #outputArgs,d3
CALL VFPrintf,<(dosBase)>
move.l (window),d1
CALL Flush
moveq #FALSE,d0
DONE RemoveFunctions
***********************************************************************************
;-------------- Remove patch of a system function
;--------------
;-------------- => a0: APTR Patchinfo
;--------------
ENTRY RemovePatch,d1-d7/a0-a3/a5/a6
movea.l a0,a5
;-------------- test if it is our patch
tst.l (spatch_Library,a5)
beq .SUCCESS
movea.l (spatch_Library,a5),a1
move.w (spatch_Offset,a5),d1
addq.w #2,d1
move.l (a1,d1.w),a1
subi.l #sphead_SIZEOF,a1
cmpi.l #PATCH_IDSTRING,(sphead_Ident,a1)
bne.b .REMOVEFAILED
movea.l (execBase).w,a6
move.l (ThisTask,a6),d0
cmp.l (sphead_Owner,a1),d0
bne.b .REMOVEFAILED
movea.l a1,a4 ; a4 = patched memory
tst.l (sphead_OriginalFunction,a4)
beq.b .SUCCESS
;-------------- restore original function
movea.l (spatch_Library,a5),a1
move.w (spatch_Offset,a5),d0
ext.l d0
movea.l d0,a0
move.l (sphead_OriginalFunction,a4),d0
CALL SetFunction,<(execBase).w>
clr.l (sphead_OriginalFunction,a4)
;-------------- free patched memory
movea.l a4,a1
move.l (Patch_SIZEOF),d0
CALL FreeMem
.SUCCESS moveq #TRUE,d0
bra.b RemovePatch_done
;--------------
.REMOVEFAILED moveq #FALSE,d0
DONE RemovePatch
***********************************************************************************
;-------------- Remove patch of a system device
;--------------
;-------------- => a0: SnoopyDeviceBase *
;--------------
ENTRY RemoveDevicePatch,d1-d7/a0-a6,idps_SIZEOF,a5
move.l a0,(idps_DeviceBase,a5)
move.l a1,(idps_BeginOfPatch,a5)
move.l a2,(idps_JumpAddress,a5)
move.l d0,(idps_SizeOfPatch,a5)
move.w d1,(idps_Offset,a5)
;-------------- test if it is our patch
movea.l (idps_DeviceBase,a5),a3 ; a3 = SnoopyDeviceBase *
movea.l (sdevbase_Device,a3),a1
move.w (idps_Offset,a5),d1
addq.w #2,d1
movea.l (a1,d1.w),a1
suba.l #sphead_ExtSIZEOF,a1
cmpi.l #PATCH_IDSTRING,(sphead_Ident,a1)
bne.b .REMOVEFAILED
movea.l (execBase).w,a6
move.l (ThisTask,a6),d0
cmp.l (sphead_Owner,a1),d0
bne.b .REMOVEFAILED
move.l a1,a4 ; a4 = patched memory
tst.l (sphead_OriginalFunction,a4)
beq.b .SUCCESS
;-------------- restore original function
movea.l (sdevbase_Device,a3),a1
move.w (idps_Offset,a5),d0
ext.l d0
movea.l d0,a0
move.l (sphead_OriginalFunction,a4),d0
CALL SetFunction,<(execBase).w>
clr.l (sphead_OriginalFunction,a4)
;-------------- free patched memory
movea.l a4,a1
move.l (idps_SizeOfPatch,a5),d0
CALL FreeMem
.SUCCESS moveq #TRUE,d0
bra.b RemoveDevicePatch_done
;--------------
.REMOVEFAILED moveq #FALSE,d0
DONE RemoveDevicePatch
***********************************************************************************
;-------------- remove any running instance of Snoopy
;--------------
ENTRY QuitSnoopyInstances,d0-d7/a0-a6
;-------------- d7 = Instance Number; if d7 == 0, remove ALL instances,
;-------------- else remove only the numbered instance
movea.l (argQuit),a0
move.l (a0),d7
beq .REMOVEALL
;-------------- stop fooling around
CALL Forbid,<(execBase).w>
;-------------- examine waiting tasks
lea (TaskWait,a6),a4
movea.l (LH_HEAD,a4),a4
.LOOP1 tst.l (LN_SUCC,a4)
beq.b .DONE1
bsr.b .FINDSNOOPY
bsr.b .REMTASK
movea.l (LN_SUCC,a4),a4
bra.b .LOOP1
;-------------- examine ready tasks
.DONE1 lea (TaskReady,a6),a4
movea.l (LH_HEAD,a4),a4
.LOOP2 tst.l (LN_SUCC,a4)
beq.b .DONE2
bsr.b .FINDSNOOPY
bsr.b .REMTASK
movea.l (LN_SUCC,a4),a4
bra.b .LOOP2
.DONE2 CALL Permit
bra QuitSnoopyInstances_done
;-------------- remove task if it fits
.REMTASK tst.w d1
beq.b .FAILREMTASK
cmp.w d7,d1
bne.b .FAILREMTASK
movea.l a4,a1
move.l #SIGBREAKF_CTRL_C,d0
CALL Signal
.FAILREMTASK rts
;-------------- trys to find out the name for a task
;--------------
;-------------- <= d0:BOOL success
;-------------- d1:LONG instance number of the task currently found
.FINDSNOOPY movea.l (LN_NAME,a4),a0
lea (taskNameFormat,pc),a1
moveq #taskNameFormat_SIZEOF-1,d0
.STRCMP move.b (a0)+,d1
cmp.b (a1)+,d1
bne.b .SKIP
dbra d0,.STRCMP
moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.l d0,d1
moveq #TRUE,d0
rts
.SKIP moveq #FALSE,d0
rts
MAX_ACTIVESNOOPYS equ MAX_INPUT
;-------------- find all active snoopy numbers and store them in InputMemory[]
.REMOVEALL lea (inputMemory),a3
CALL Forbid,<(execBase).w>
lea (TaskWait,a6),a4
bsr.b .FINDSNOOPYS
lea (TaskReady,a6),a4
bsr.b .FINDSNOOPYS
CALL Permit
;-------------- now of course I could be write a quicksort algorithm, but
;-------------- really the following method is easier: I just try to find
;-------------- the maximum element, break it, then start the loop again
move.l a3,d7
subi.l #inputMemory+1,d7
.ra_Loop move.l d7,d2 ; loop counter
lea (inputMemory),a3
moveq #0,d0 ; current maximum
.ra_FindMax move.b (a3),d1
cmp.b d1,d0
bge.b .ra_NotMax
move.b d1,d0
move.l a3,a2
.ra_NotMax addq.l #1,a3
dbra d2,.ra_FindMax
tst d0
beq.b QuitSnoopyInstances_done
clr.b (a2)
;-------------- clear this element
lea (outputArgs),a1
move.l d0,(a1)
lea (taskNameFormat,pc),a0
lea (currentTaskName),a2
jsr SPrintf
lea (currentTaskName),a1
CALL FindTask
tst.l d0
beq.b .ra_Loop
movea.l d0,a1
move.l #SIGBREAKF_CTRL_C,d0
CALL Signal
bra.b .ra_Loop
.FINDSNOOPYS movea.l (LH_HEAD,a4),a4
.fs_LOOP tst.l (LN_SUCC,a4)
beq.b .fs_DONE
bsr .FINDSNOOPY
tst.b d0
beq.b .fs_SKIP
move.b d1,(a3)+
.fs_SKIP movea.l (LN_SUCC,a4),a4
bra.b .fs_LOOP
.fs_DONE rts
DONE QuitSnoopyInstances
***********************************************************************************
;-------------- note: I use some very old code here stolen from a program I wrote
;-------------- some year ago together with a friend of mine (Stefan Scherer);
;-------------- this code isn't well documented but it works just fine so why bother....
ENTRY ReadWBArgs,d0-d7/a0-a6
lea (TTHStruktur),a3
move.l (tth_WBStartup,a3),d0
beq ReadWBArgs_done
tst.l (argRdargs)
bne ReadWBArgs_done
clr.l (argRdargs)
;-------------- normal startup from workbench
.vonWorkbench movea.l d0,a3
move.l (sm_NumArgs,a3),d0
movea.l (sm_ArgList,a3),a3
cmpi.l #1,d0
beq.b .DEFSTART
lea (wa_SIZEOF,a3),a3
.DEFSTART move.l (wa_Lock,a3),d1 ; DirLock zeigt auf
CALL CurrentDir,<(dosBase)> ; Pfad des Programms
move.l (wa_Name,a3),a0
.LeseIcon CALL GetDiskObject,<(iconBase)> ; ".info"-Datei lesen
BRF d0,ReadWBArgs_done ; Fehler, dann weiter
;-------------- Tool Types auswerten
move.l d0,a3
cmpi.b #WBPROJECT,(do_PAD_BYTE-1,a3)
beq .USEPROJECT
move.l (do_ToolTypes,a3),a3
move.l a3,a0
lea (TTScript,pc),a1
push a0
CALL FindToolType
pop a0
move.l d0,(argScript)
.READTOOLTYPES movea.l a0,a5
lea (TTIncdir,pc),a1
movea.l a5,a0
CALL FindToolType
move.l d0,(argIncdir)
lea (TTOutput,pc),a1
movea.l a5,a0
CALL FindToolType
move.l d0,(argOutput)
lea (TTPri,pc),a1
movea.l a5,a0
CALL FindToolType
tst.l d0
beq.b .SKIPPRI
movea.l d0,a0
moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.l d0,(priority)
.SKIPPRI lea (TTSticky,pc),a1
lea (argSticky),a2
bsr.b .GETBOOLEAN
lea (TTNoSegTracker,pc),a1
lea (argNoSegTracker),a2
bsr.b .GETBOOLEAN
lea (TTMatch,pc),a1
lea (argMatch),a2
bsr.b .GETBOOLEAN
lea (TTTaskInfo,pc),a1
lea (argTaskInfo),a2
bsr.b .GETBOOLEAN
bra.b ReadWBArgs_done
.GETBOOLEAN movea.l a5,a0
push a2
CALL FindToolType
pop a1
tst.l d0
beq.b .ISNTBOOL
movea.l d0,a0
jsr FindBooleanKeyword
.ISNTBOOL rts
.USEPROJECT push a3
lea (TTHStruktur),a3
move.l (tth_WBStartup,a3),a3
move.l (sm_ArgList,a3),a3
lea (wa_SIZEOF,a3),a3
move.l (wa_Name,a3),(argScript)
pop a3
move.l (do_ToolTypes,a3),a3
move.l a3,a0
bra .READTOOLTYPES
DONE ReadWBArgs
***********************************************************************************
cstr "$VER: ",IDSTRING
;-------------- library definitions
dosName cstr "dos.library"
intName cstr "intuition.library"
iconName cstr "icon.library"
;-------------- global text messages
defaultScript cstr DEFAULTSCRIPT
TIenabledMsg cstr 'TaskInfo enabled\n'
TIdisabledMsg cstr 'TaskInfo disabled\n'
taskinfoMsg cstr 'Task %08lx : "%s"\n'
taskbcplMsg cstr 'Task %08lx : "%b"\n'
helloMsg cstr "Welcome to
",IDSTRING,"[%ld]
- written by ",AUTHORSTRING,"\n"
disableoutMsg cstr "
Output disabled - press CTRL+E to enable again.
\n"
enableoutMsg cstr "
Output enabled - press CTRL+D to disable.
\n"
windowName cstr "con:0/0/640/150/",IDSTRING
;-------------- template for dos/ReadArgs()
argTemplate dc.b "SCRIPT,"
dc.b "TASKINFO/S,"
dc.b "OUTPUT/K,"
dc.b "PRI/N,"
dc.b "SHOW/K/M,"
dc.b "STICKY/S,"
dc.b "MATCH/S,"
dc.b "QUIT/K/N,"
dc.b "INCDIR/K,"
dc.b "NOSEGTRACKER/S"
dc.b 0
;-------------- workbench tooltypes
TTScript cstr "SCRIPT"
TTPri cstr "PRI"
TTOutput cstr "OUTPUT"
TTSticky cstr "STICKY"
TTNoSegTracker cstr "NOSEGTRACKER"
TTTaskInfo cstr "TASKINFO"
TTMatch cstr "MATCH"
TTIncdir cstr "INCDIR"
;-------------- name of SegTracker semaphore
SegTrackerName cstr "SegTracker"
SegTrackerMsg cstr "$%08lx - %s : Hunk %ld, Offset $%08lx, SegList $%08lx\n"
SegTrackerMsgTI cstr 'PC=$%lx,N="%s",H=%ld,O=$%lx,S=$%lx,A=%lx,T="%s"\n'
SegTrackerFail cstr "(Segment not found)\n"
SegTrackerOn dc.b FALSE
;-------------- error messages for this module
nowindowErr cstr "ERROR, cannot open output stream"
nomsgportErr cstr "ERROR, cannot create msgport"
closesnoopyErr dc.b 10,'*** WARNING *** Something else has patched the vectors Snoopy looks into'
dc.b 10,'You will have to wait for the other program to finish and try Snoopy again'
dc.b 10,'The function I have trouble with is the one with the template'
dc.b 10,'"%s"',10,0
closeBeginIoErr cstr "ERROR, cannot remove DEV_BEGINIO() for %s\n",0
closeAbortIoErr cstr "ERROR, cannot remove DEV_ABORTIO() for %s\n",0
activeCallsErr cstr "ERROR, %ld calls still working",0
newlineMsg cstr '\n'
;-------------- new: flexible naming schedule
taskNameFormat dc.b "Snoopy Task."
taskNameFormat_SIZEOF equ *-taskNameFormat
cstr "%ld",0
taskPortFormat cstr "Snoopy Port.%ld",0
;-------------- success/failure messages
SuccessMsg cstr "YES"
FailureMsg cstr "NO"
;-------------- internal messages : not documented (try to find out yourself....)
abortIOMsg cstr "AbortIO"
beginIOMsg cstr "BeginIO"
;-------------- user messages
DebugDefTempMsg dc.b "**** Userfunction before call *********************************************",10
dc.b "Dx:%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10
dc.b "Ax:%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10
dc.b "():%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10
dc.b "**** Userfunction after call",10
dc.b "Dx:%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10
dc.b "Ax:%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10
dc.b "():%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10,0
section memory,bss
;-------------- library bases (guess what)
defs.l dosBase,1
defs.l intBase,1
defs.l iconBase,1
;-------------- all internal lists
defs.b hides,LH_SIZE
defs.b shows,LH_SIZE
defs.b bases,LH_SIZE
defs.b watches,LH_SIZE
defs.b deviceBases,LH_SIZE
defs.b aliases,LH_SIZE
defs.b defines,LH_SIZE
defs.b resources,LH_SIZE
;-------------- other global data
defs.l SegTracker,1 ; SegTracker semaphore or NULL if it doesn't exist
defs.l myport,1 ; port where all Snoopy messages arrive
defs.l window,1 ; pointer to current output channel
defs.l thistask,1 ; pointer to my own task
defs.l ActiveCalls,1 ; counts the number of active calls
;-------------- internal data (locally used only within this module)
answersignal ds.l 1 ; the signalmask used for SendMsg()/GetMsg() answers
waitsignals ds.l 1 ; signals to Wait() for
message ds.l 1 ; last message recieved by GetMsg()
signals ds.l 1 ; signals actually recieved by Wait()
lastMessage ds.l 1 ; pointer to last message (for SKIPSIMILAR)
;-------------- stuff for ReadArgs
argRdargs ds.l 1 ; for allocated memory (dos.library INTERNALs)
argFirst
defs.l argScript,1 ; name of scriptfile or NULL for defaults
defs.l argTaskInfo,1 ; TRUE if extended task info is to be given
defs.l argOutput,1 ; name of redirected filename or NULL for the window
defs.l argPri,1 ; priority number or NULL
defs.l argShow,1 ; array of tasknames to show or NULL
defs.l argSticky,1 ; KEEP STICKY
defs.l argMatch,1 ; use exact matching
defs.l argQuit,1 ; remove snoopy instances
defs.l argIncdir,1
defs.l argNoSegTracker,1
outputactive ds.b 1
defs.b showsactive,1
;-------------- contains the actual task/port names made by BuildSnoopysTaskname()
currentTaskName ds.b 40
currentPortName ds.b 40
currentInstance ds.l 1 ; instance counter
;-------------- segtracker output data
st_SegAddress ds.l 1
st_SegName ds.l 1
st_SegHunk ds.l 1
st_SegOffset ds.l 1
st_SegList ds.l 1
st_SegTaskAddr ds.l 1
st_SegFilename ds.l 1
errorMsgBuffer ds.b 256
***********************************************************************************
;--------------